package order

import (
	"errors"
	"net/http"

	"gitee.com/zoneaurora/shop/internal/common"
	"gitee.com/zoneaurora/shop/internal/model"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type requestParams struct {
  Status int
  Page int
  PageSize int
}

func GetCurrentOrder(c *gin.Context) {
  db := common.DB()

  // 获取请求参数
  var params requestParams
  c.BindQuery(&params)

  // 当前用户
  iUser, _ := c.Get("user")
  user := iUser.(model.User)

  var order model.Order
  if db.Where("status = ? AND user_id = ?", params.Status, user.ID).
      First(&order).Error != nil {
    var newOrder model.Order
    newOrder.UserID = user.ID
    if db.Create(&newOrder).Error != nil {
      common.JSON(c, http.StatusInternalServerError, "获取订单失败", nil)
      return
    }
    common.JSON(c, http.StatusOK, "获取订单成功", newOrder)
    return
  }
  common.JSON(c, http.StatusOK, "获取订单成功", order)
}

func PayForOrder(c *gin.Context) {
  db := common.DB()

  // 获取请求参数
  var params model.Order
  c.Bind(&params)

  // 获取用户数据
  iUser, _ := c.Get("user")
  user := iUser.(model.User)
  if user.Telephone == "" || user.Address == "" {
    common.JSON(c, http.StatusBadRequest, "请检查用户信息", nil)
    return
  }

  // 计算总价
  var totalPrice float64 
  var orderItem []model.OrderItem
  if db.Where("order_id = ?", params.ID).Find(&orderItem).Error != nil {
    common.JSON(c, http.StatusBadRequest, "找不到订单数据", nil)
    return
  }
  for _, v := range orderItem {
    totalPrice += v.Price * float64(v.Number)
  }

  // 判断余额是否足够
  if totalPrice > user.Money {
    common.JSON(c, http.StatusBadRequest, "余额不足，请先充值", nil)
    return
  }

  // 开启事务
  err := db.Transaction(func (tx *gorm.DB) error {
    var userModel model.User
    var order model.Order
    var err error
    // 扣除用户余额
    err = tx.First(&userModel, user.ID).
      Update("money", userModel.Money - totalPrice).Error
    if err != nil {
      return errors.New("用户余额不足")
    }
    // 扣除商品库存
    for _, v := range orderItem {
      var product model.Product
      res := tx.First(&product, v.ProductID)
      if res.Error != nil {
        return errors.New("服务器异常")
      }
      if product.Number - v.Number < 0 {
        return errors.New("库存不足")
      }
      err = res.Update("number", product.Number - v.Number).Error
      if err != nil {
        return errors.New("服务器异常")
      }
    }
    // 更新订单状态
    err = tx.First(&order, params.ID).Updates(model.Order{
      Status: 1,
      Address: user.Address,
      Telephone: user.Telephone,
    }).Error
    if err != nil {
      return errors.New("服务器异常")
    }
    return nil
  })
  if err != nil {
    common.JSON(c, http.StatusBadRequest, err.Error(), nil)
    return
  }
  common.JSON(c, http.StatusOK, "支付成功", nil)
}

func GetOrders(c *gin.Context) {
  db := common.DB()

  // 解析请求参数
  var params requestParams
  c.BindQuery(&params)

  // 当前用户
  iUser, _ := c.Get("user")
  user := iUser.(model.User)

  var total int64
  var orders []model.Order
  if params.Status == 1 {
    if db.Table("orders").Where("user_id = ? ", user.ID).
        Where("status = 1 OR status = 2").Count(&total).Error != nil {
      common.JSON(c, http.StatusBadRequest, "查询失败", nil)
      return
    }
    if db.Where(
        "user_id = ?", user.ID).
        Where("status = 1 OR status = 2").
        Offset((params.Page-1) * params.PageSize).Limit(params.PageSize).
        Order("updated_at desc").Find(&orders).Error != nil {
      common.JSON(c, http.StatusBadRequest, "查询失败", nil)
      return
    }
    common.JSON(c, http.StatusOK, "查询成功", gin.H{
      "list": orders,
      "total": total,
    })
    return
  }
  if db.Table("orders").Where(
      "user_id = ?", user.ID).Not("status = ?", 0).
      Count(&total).Error != nil {
    common.JSON(c, http.StatusBadRequest, "查询失败", nil)
    return
  }
  if db.Where("user_id = ?", user.ID).Not("status = ?", 0).
      Offset((params.Page-1) * params.PageSize).Limit(params.PageSize).
      Order("updated_at desc").Find(&orders).Error != nil {
    common.JSON(c, http.StatusBadRequest, "查询失败", nil)
    return
  }
  common.JSON(c, http.StatusOK, "查询成功", gin.H{
    "list": orders,
    "total": total,
  })
}

func FinishOrder(c *gin.Context) {
  db := common.DB()

  // 当前用户
  iUser, _ := c.Get("user")
  user := iUser.(model.User)

  id := c.Param("id")
  var order model.Order
  if db.Where("id = ? AND user_id = ?", id, user.ID).
      First(&order).Update("status", 3).Error != nil {
    common.JSON(c, http.StatusBadRequest, "操作出错", nil)
    return
  }
	common.JSON(c, http.StatusOK, "订单已完成", nil)
}
